/************************************************************************************
 *
 * memo:
 * https://blog.csdn.net/cjbct/article/details/79266057    std::shared_ptr
 * https://blog.csdn.net/czyt1988/article/details/21093451 std::bind
 * **********************************************************************************/

#include "commserialsingle.h"

#include <mutex>  //call_once once_flag
#include <memory>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>

std::shared_ptr<CommSerialSingle> CommSerialSingle::_S(new CommSerialSingle(), CommSerialSingle::Destory);

CommSerialSingle::CommSerialSingle()
    : m_PortInfo(nullptr)
{
    qDebug() << "CommSerial constructor";

    m_Port = new QSerialPort;

    //default param
    m_Port->setBaudRate(QSerialPort::Baud115200);
    m_Port->setDataBits(QSerialPort::Data8);
    m_Port->setParity(QSerialPort::NoParity);
    m_Port->setStopBits(QSerialPort::OneStop);
    m_Port->setFlowControl(QSerialPort::NoFlowControl);
}

CommSerialSingle::~CommSerialSingle()
{
    delete m_Port;
    delete m_PortInfo;

    qDebug() << "CommSerial destructor";
}

std::shared_ptr<CommSerialSingle> CommSerialSingle::GetInstance()
{
#if 0
    static std::once_flag oc;

    std::call_once(oc, []{std::shared_ptr<CommSerialSingle> \
                _S(new CommSerialSingle, CommSerialSingle::Destory);});
#endif
    return _S;
}

void CommSerialSingle::Destory(CommSerialSingle *s)
{
    delete s;
}

void CommSerialSingle::OpenPort(QString& name)
{
    if(nullptr != m_PortInfo || m_Port->isOpen()) {
        ClosePort();
    }
    m_PortInfo = new QSerialPortInfo(name);
    m_Port->setPort(*m_PortInfo);
    m_Port->open(QIODevice::ReadWrite);
}

void CommSerialSingle::ClosePort()
{
    if(m_Port->isOpen()) m_Port->close();
    delete m_PortInfo;
    m_PortInfo = nullptr;
}

QSerialPort* CommSerialSingle::GetPort()
{
    return m_Port;
}
